A “thread” is the basic unit of CPU (central processing unit) utilization. An individual thread has little non-shared state, usually just its own register state and its own stack. Normally, a group of peer threads share code, address space, and operating system resources. The environment in which a thread executes is called a task. A task does nothing if it does not contain threads, and a thread can only be in one task.
The “thread” functions as a placeholder or container for information associated with a single user of a program that can handle multiple concurrent users. From the program's point-of-view, the thread is the information needed to serve the one individual user or a particular service request. If multiple users are using the program or concurrent requests from other programs occur, a separate thread is created and maintained for each of them. The thread allows a program to know which user is being served as the program alternately gets re-entered on behalf of different users. (One way in which thread information is kept is by storing it in a special data area and putting the address of that data area in a register. The operating system always saves the contents of the register when the program is interrupted and restores it when it gives the program control again.)
In the context of “threads” and “tasks” and “multitasking” and “multithreading,”“multithreading” and “tasks” are often confused. As used herein, “tasks” are made up of and contain one or more “threads.” Multiple tasks may be instantiated and appear to be running simultaneously. While some computers can only execute one program instruction at a time, because they operate so fast, they appear to run many programs and serve many users simultaneously. The computer operating system gives each program a “turn” at running, then, based upon various external and internal events or happenings, the operating system requires the current program or task to wait while another program gets a turn. Each of these programs is viewed by the operating system as a “task” for which certain resources are identified and kept track of. The operating system manages each application program as a separate task and lets the user look at and control items on a “task list.”
By way of illustration, if the program initiates an I/O request, such as reading a file or writing to a printer, it creates a thread so that the program will be reentered at the right place when the I/O operation completes. Meanwhile, other concurrent uses of the program are maintained on other threads. The extensive sharing of code, address space, and operating system resources among threads make the creation of threads and switching between threads relatively inexpensive in terms of computer resources.
Moreover, most modern operating systems provide support for both multitasking and multithreading. They also allow multithreading within program processes so that the system is saved the overhead of creating a new process for each thread.
Another aspect of multi-thread operations is “thread safety.” As used herein, “thread-safe” is a term used to describe a routine that can be called from multiple programming threads without unwanted interaction between the threads. Thread safety is of particular importance to Java programmers, since Java is a programming language that provides built-in support for threads. By using thread-safe routines, the risk that one thread will interfere and modify data elements of another thread is eliminated by circumventing potential data race situations with coordinated access to shared data.
It is possible to ensure that a routine is thread-safe by making sure that concurrent threads use synchronized algorithms that cooperate with each other, and confining the address of a shared object to one thread whenever an unsynchronized algorithm is active.
Modern operating systems typically provide a set of application program interfaces that allow a programmer to include thread support in a program. Higher-level program development tools and application subsystems and “middleware” also offer thread management facilities. Object-oriented programming languages also accommodate and encourage multithreading in several ways. For example, Java supports multithreading by including synchronization modifiers in the language syntax, by providing classes developed for multithreading that can be inherited by other classes, and by doing background “garbage collection” (recovering data areas that are no longer being used) for multiple threads.
One particular challenge is multi-threading in the context of single-threaded code logic. Moreover, single threaded logic is non-trivial. It is the low level low level glue that provides I/O, opening and closing files, writing output to the monitor, printer, and diskdrives, services interrupts, traps exceptions, and the like. The single threaded logic applications provide vital substance to the high level applications. Single-threaded code logic is usually in the form of APIs or subroutines that have areas of memory or variables that cannot be shared by multiple threads of execution simultaneously. This is usually due to fixed memory addressing logic and/or shared resource usage. The problem arises because calling a single threaded application from within a multi-threaded process or sub-process can cause memory over-writes and other problems. The single threaded application is not “thread safe.” Thus, a need exists for the capability of incorporating single-threaded code logic into a multi-threaded software environment.